(function () {
    var Tools = {
      getRandom: function (min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min;
      },
      getColor: function () {
        var r = this.getRandom(0, 255);
        var g = this.getRandom(0, 255);
        var b = this.getRandom(0, 255);
        return "rgb(" + r + "," + g + "," + b + ")";
      }
    };
    window.Tools = Tools;
  })();



(function () {
    function Food (option) {
        option = option instanceof Object ? option : {};
        this.width = option.width || 20;
        this.height = option.height || 20;
        this.x = option.x || 0;
        this.y = option.y || 0;
        this.color = option.color || "green";
        this.elements = [];
    }
    const ab = "absolute";
    Food.prototype.render = function (map) {
        this.x = Tools.getRandom(0,map.clientWidth / this.width - 1) * this.width;
        this.y = Tools.getRandom(0,map.clientHeight / this.height - 1) * this.height;

        const ele = document.createElement("div");
        ele.style.width = this.width + "px";
        ele.style.height = this.height + "px";
        ele.style.left = this.x + "px";
        ele.style.top = this.y + "px";
        ele.style.backgroundColor = this.color;
        ele.style.position = ab;
        map.appendChild(ele);
        this.elements.push(ele);
    }
    Food.prototype.remove = function(map,i) {
        map.removeChild(this.elements[i]);
        this.elements.splice(i, 1);
    }
    window.Food = Food;
})();


(function () {
    const ps = "absolute";
    function Snake (option) {
        option = option instanceof Object ? option : {};
        this.width = option.width | 20;
        this.height = option.height || 20;
        this.body = [
            {x: 3,y: 2,color: "red"},
            {x: 2,y: 2,color: "blue"},
            {x: 1,y: 2,color: "blue"}
        ];
        this.direction = "right";
        this.elements = [];
    }
    Snake.prototype.render = function (map) {
        for (var i = 0,length = this.body.length; i < length; i++) {
            const SnakeBody = this.body[i];
            const ele = document.createElement("div");
            ele.style.width = this.width + "px";
            ele.style.height = this.height + "px";
            ele.style.position = ps;
            ele.style.left = SnakeBody.x * this.width + "px";    
            ele.style.top = SnakeBody.y * this.height + "px";
            ele.style.backgroundColor = SnakeBody.color;
            map.appendChild(ele);
            this.elements.push(ele);    
        }
        
    }
    Snake.prototype.move = function (map) {

        for (var i = this.body.length-1; i > 0; i--) {
            this.body[i].x = this.body[i-1].x;
            this.body[i].y = this.body[i-1].y;
        }
        switch (this.direction){
            case "right":
                this.body[0].x += 1;
                break;
            case "left":
                this.body[0].x -= 1;
                break;
            case "top":
                this.body[0].y -= 1;
                break;
            case "bottom":
                this.body[0].y += 1;
                break; 
        }
    }
    Snake.prototype.remove = function (map) {
        for (var i = this.elements.length - 1; i >= 0; i--) {
            map.removeChild(this.elements[i]);
        }
        this.elements = [];
    }
    window.Snake = Snake;
})();



(function () {
    function Game (map) {
        this.food = new Food();
        this.snake = new Snake();
        this.map = map;
        that = this;
    }
    Game.prototype.start = function () {
        this.food.render(this.map);
        this.snake.render(this.map);
        runsanke();
        SnakeKeyCode();
    }
    function runsanke () {
        var timer = setInterval(function () {
            that.snake.move();
            that.snake.remove(that.map);
            that.snake.render(that.map);
            const maxX = that.map.offsetWidth / that.snake.width;
            const maxY = that.map.offsetHeight / that.snake.height;
            const snakeHeadx = that.snake.body[0].x;
            const snakeHeady = that.snake.body[0].y;
            const snakex = snakeHeadx * that.snake.width;
            const snakey = snakeHeady * that.snake.height;
            for (var i = 0 ; i < that.food.elements.length ; i++) {
                if (that.food.elements[i].offsetLeft === snakex && that.food.elements[i].offsetTop === snakey) {
                    that.food.remove(that.map,i);
                    that.food.render(that.map);
                    const last = that.snake.body[that.snake.body.length - 1];
                    that.snake.body.push({
                        x: last.x,
                        y: last.y,
                        color: last.color
                    });
                }
            }
            for (var i = 1; i < that.snake.body.length ; i++) {
                if (snakeHeadx === that.snake.body[i].x && snakeHeady === that.snake.body[i].y) {
                    clearInterval(timer);
                    alert("Game over");
                }
            } 
            if (snakeHeadx >= maxX || snakeHeadx < 0 || snakeHeady >= maxY || snakeHeady < 0) {
                clearInterval(timer);
                alert("Game over");
            }
        },150) 
    }
    function SnakeKeyCode () {
        document.onkeydown = function (e) {
            switch (e.keyCode) {
                case 37:
                    if (that.snake.direction !== "right") {
                      that.snake.direction = "left";
                    }
                    break;
                case 38:
                    if (that.snake.direction !== "bottom") {
                      that.snake.direction = "top";  
                    }
                    break;
                case 39:
                    if (that.snake.direction !== "left"){
                       that.snake.direction = "right"; 
                    }
                    break;
                case 40:
                    if (that.snake.direction !== "top"){
                       that.snake.direction = "bottom"; 
                    }
                    break;    
            }
        } 
    }
    window.Game = Game;
})();